/****
 * Copyright (C) 2006 dNux Team
 *                                                            ****
 * This program is free software; you can redistribute it and/or *
 * modify under the terms of the GNU General Public License as   *
 * published by the Free Software Foundation;                    *
 * either version 2 of the License.                              *
 *                                                               *
 * This program is distributed in the hope that it will be       *
 * useful, but WITHOUT ANY WARRANTY; without even the implied    *
 * warranty of without even the implied waranty of               *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.          *
 * See the GNU General Public License for more details.          *
 *                                                               *
 * You should have received a copy of the                        *
 * GNU General Public License                                    *
 * along with this program; if not, write to the                 *
 * Free Software Foundation, Inc.,                               *
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. *
 *                                                               *
 ****                                                         ****/

void
list_del(d_check_t *check)
{
  int a=12, b=13;
  int *c;

  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;

  list = d_list_new();
  d_list_pushback(list, &a);
  d_list_pushback(list, &b);

  it = d_list_begin(list);
  d_list_del(it);
  d_list_free_iterator(&it);

  it = d_list_begin(list);
  d_list_value(it, &c);
  if (*c == 13) {
    d_check_add(check, D_CHECK_OK, "list::del => work as expected.");
  } else {
    d_check_add(check, D_CHECK_ERROR, "list::del => doesn't work has expected.");
  }
  d_list_free_iterator(&it);
  d_list_free(&list);

}


void
list_begin(d_check_t *check)
{
  int a=13, b=12;
  int *c;
  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;

  list = d_list_new();
  it = d_list_begin(list);
  if (it) {
    d_check_add(check, D_CHECK_ERROR, "list::begin => it should be null here.");
    d_list_free_iterator(&it);
    goto error;
  }

  d_list_pushback(list, &a);
  d_list_pushback(list, &b);
  it = d_list_begin(list);
  if (!it) {
    d_check_add(check, D_CHECK_ERROR, "list::begin => it should'nt be null here.");
    goto error;
  }

  d_list_value(it, &c);
  if (*c == a) {
    d_check_add(check, D_CHECK_OK, "list::begin => point on the good element.");
  } else {
    d_check_add(check, D_CHECK_ERROR, "list::begin => should'nt point here.");
  }

  d_list_free_iterator(&it);

 error:
  d_list_free(&list);
  return;
}


void list_new(d_check_t *check)
{
  d_list_t *list=NULL;
  list = d_list_new();
  if (list != NULL) {
    d_check_add(check, D_CHECK_OK, "list::new => list created");
    d_list_free(&list);
  }
  else {
    d_check_add(check, D_CHECK_ERROR, "list::new => list can't be created.");
  }
}


void
list_push(d_check_t *check)
{
  int a=9, b=12;
  int *c=NULL;
  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;

  list = d_list_new();

  d_list_push(list, &a);
  d_list_push(list, &b);
  
  it = d_list_begin(list);
  d_list_value(it, &c);
  if (*c == b) {
    d_list_next(&it);
    d_list_value(it, &c);
    if (*c == a) {
      d_check_add(check, D_CHECK_OK, "list::push => data order is ok.");
    }
    else {
      d_check_add(check, D_CHECK_ERROR, "list::push => value not excepted.");
    }
  }
  else {
    d_check_add(check, D_CHECK_ERROR, "list::push => value not excepted.");
  }
  d_list_free_iterator(&it);

  d_list_free(&list);
}


void
list_free_iterator(d_check_t *check)
{
  int a=12;
  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;


  list = d_list_new();
  d_list_push(list, &a);

  it = d_list_begin(list);
  if (! it) {
    d_check_add(check, D_CHECK_ERROR, "list::free_iterator => d_list_begin doen't work.");
  } else {
    d_list_free_iterator(&it);
    if (it) {
      d_check_add(check, D_CHECK_ERROR, "list::free_iterator => it not NULL.");
    } else {
      d_check_add(check, D_CHECK_OK, "list::free_iterator => it is NULL.");
    }
  }
  d_list_free(&list);
}


d_bool_t list_free_func_ok;

void
list_free_f(void *ptr)
{
  list_free_func_ok = d_true;
}

void
list_free_func(d_check_t *check)
{
  int a=12;
  d_list_t *list=NULL;

  list_free_func_ok = d_false;
  list = d_list_new();
  d_list_set_free_func(list, list_free_f);
  d_list_push(list, &a);
  d_list_free(&list);

  if (list_free_func_ok) {
    d_check_add(check, D_CHECK_OK, "list::free_func => list_free_f was called.");
  } else {
    d_check_add(check, D_CHECK_ERROR, "list::free_func => list_free_f wasn't called.");
  }
}


void
list_clear(d_check_t *check)
{
  int a=12;

  d_list_t *list=NULL;

  list = d_list_new();
  d_list_push(list, &a);
  d_list_clear(list);
  if (d_list_length(list) == 0) {
    d_check_add(check, D_CHECK_OK, "list::clear => list is clear");
  } else {
    d_check_add(check, D_CHECK_ERROR, "list::clear => list is not clear");
  }
  d_list_free(&list);
}


void
list_prev(d_check_t *check)
{
  int a=12, b=13, c=14;
  int *d;

  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;

  list = d_list_new();
  d_list_pushback(list, &a);
  d_list_pushback(list, &b);
  d_list_pushback(list, &c);
  
  it = d_list_end(list);
  d_list_prev(&it);
  d_list_value(it, &d);
  if (*d != b) {
    d_check_add(check, D_CHECK_ERROR, "list::prev => it should have b value.");
    d_list_free_iterator(&it);
    goto error;
  }
  d_list_prev(&it);
  d_list_value(it, &d);
  d_list_free_iterator(&it);
  if (*d != a) {
    d_check_add(check, D_CHECK_ERROR, "list::prev => it should hava a value.");
    goto error;
  }

  d_check_add(check, D_CHECK_OK, "list::prev => tested.");

 error:
  d_list_free(&list);
}


void
list_length(d_check_t *check)
{
  int a=12, b=13, c=14;
  d_list_t *list=NULL;

  list = d_list_new();

  if (d_list_length(list) != 0) {
    d_check_add(check, D_CHECK_ERROR, "list::length => should be 0 here.");
    goto error;
  }

  d_list_push(list, &a);
  if (d_list_length(list) != 1) {
    d_check_add(check, D_CHECK_ERROR, "list::length => should be 1 here.");
    goto error;
  }

  d_list_pushback(list, &b);
  d_list_pushback(list, &c);
  if (d_list_length(list) != 3) {
    d_check_add(check, D_CHECK_ERROR, "list::length => should be 3 here.");
    goto error;
  }

  d_check_add(check, D_CHECK_OK, "list::length => tested.");
 error:
  d_list_free(&list);
  return;
}


void
list_iterator_valid(d_check_t *check)
{
  int a=12, b=13;

  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;

  list = d_list_new();
  d_list_pushback(list, &a);
  d_list_pushback(list, &b);

  it = d_list_begin(list);
  if (! d_list_iterator_valid(it)) {
    d_check_add(check, D_CHECK_ERROR, "list::iterator_valid => it should be valid here.");
    goto error;
  }

  d_list_next(&it);
  if (! d_list_iterator_valid(it)) {
    d_check_add(check, D_CHECK_ERROR, "list::iterator_valid => it should be valid here.");
    goto error;
  }

  d_list_next(&it);
  if (d_list_iterator_valid(it)) {
    d_check_add(check, D_CHECK_ERROR, "list::iterator_valid => it should'nt be valid here.");
    goto error;
  }

  d_check_add(check, D_CHECK_OK, "list::iterator_valid => tested.");

 error:
  d_list_free_iterator(&it);
  d_list_free(&list);
  return;
}


void
list_free(d_check_t *check)
{
  d_list_t *list=NULL;
  list = d_list_new();
  if (list) {
    d_list_free(&list);
    if (! list) {
      d_check_add(check, D_CHECK_OK, "list::free => list created & free as except.");
    } else {
      d_check_add(check, D_CHECK_ERROR, "list::free => list created but not free.");
    }
  } else {
    d_check_add(check, D_CHECK_ERROR, "list::free => list can't be created.");
  }
}


void
list_at(d_check_t *check)
{
  int a=2, b=3, c=4;
  int *d;

  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;

  list = d_list_new();
  d_list_push(list, &a);
  d_list_push(list, &b);
  d_list_push(list, &c);

  it = d_list_at(list, 75);
  if (it) {
    d_check_add(check, D_CHECK_ERROR, "list::at => it should be null here.");
    d_list_free_iterator(&it);
    goto error;
  }

  it = d_list_at(list, 1);
  d_list_value(it, &d);
  d_list_free_iterator(&it);
  if (*d != b) {
    d_check_add(check, D_CHECK_ERROR, "list::at => it should have b value.");
    goto error;
  }
  
  it = d_list_at(list, 2);
  d_list_value(it, &d);
  d_list_free_iterator(&it);
  if (*d != a) {
    d_check_add(check, D_CHECK_ERROR, "list::at => it should have a value.");
  }

  d_check_add(check, D_CHECK_OK, "list::at => verified.");
 error:
  d_list_free(&list);
  return;
}


void
list_pushback(d_check_t *check)
{
  int a=9, b=12;
  int *c=NULL;
  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;

  list = d_list_new();

  d_list_pushback(list, &a);
  d_list_pushback(list, &b);
  
  it = d_list_begin(list);
  d_list_value(it, &c);
  if (*c == a) {
    d_list_next(&it);
    d_list_value(it, &c);
    if (*c == b) {
      d_check_add(check, D_CHECK_OK, "list::pushback => data order is ok.");
    }
    else {
      d_check_add(check, D_CHECK_ERROR, "list::pushback => value not excepted.");
    }
  }
  else {
    d_check_add(check, D_CHECK_ERROR, "list::pushback => value not excepted.");
  }
  d_list_free_iterator(&it);

  d_list_free(&list);
}


void
list_next(d_check_t *check)
{
  int a=12, b=13, c=14;
  int *d;

  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;

  list = d_list_new();
  d_list_pushback(list, &a);
  d_list_pushback(list, &b);
  d_list_pushback(list, &c);
  
  it = d_list_begin(list);
  d_list_next(&it);
  d_list_value(it, &d);
  if (*d != b) {
    d_check_add(check, D_CHECK_ERROR, "list::next => it should have b value.");
    d_list_free_iterator(&it);
    goto error;
  }
  d_list_next(&it);
  d_list_value(it, &d);
  d_list_free_iterator(&it);
  if (*d != c) {
    d_check_add(check, D_CHECK_ERROR, "list::next => it should hava c value.");
    goto error;
  }

  d_check_add(check, D_CHECK_OK, "list::next => tested.");

 error:
  d_list_free(&list);
}


void
list_end(d_check_t *check)
{
  int a=13, b=12;
  int *c;
  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;

  list = d_list_new();
  it = d_list_end(list);
  if (it) {
    d_check_add(check, D_CHECK_ERROR, "list::end => it should be null here.");
    d_list_free_iterator(&it);
    goto error;
  }

  d_list_pushback(list, &a);
  d_list_pushback(list, &b);
  it = d_list_end(list);
  if (!it) {
    d_check_add(check, D_CHECK_ERROR, "list::end => it should'nt be null here.");
    goto error;
  }

  d_list_value(it, &c);
  if (*c == b) {
    d_check_add(check, D_CHECK_OK, "list::end => point on the good element.");
  } else {
    d_check_add(check, D_CHECK_ERROR, "list::end => should'nt point here.");
  }

  d_list_free_iterator(&it);

 error:
  d_list_free(&list);
  return;
}


void
list_value(d_check_t *check)
{
  int a=12;
  int *b;

  d_list_t *list=NULL;
  d_list_iterator_t *it=NULL;

  list = d_list_new();
  d_list_push(list, &a);
  it = d_list_begin(list);
  d_list_value(it, &b);
  if (*b == a) {
    d_check_add(check, D_CHECK_OK, "list::value is correct");
  } else {
    d_check_add(check, D_CHECK_ERROR, "list::value isn't correct");
  }
  d_list_free_iterator(&it);
  d_list_free(&list);

}

void
list_tests(d_check_t *check)
{
  fprintf(stdout, ">> list_tests <<\n");
  list_new(check);
  list_free(check);
  list_free_func(check);
  list_free_iterator(check);
  list_begin(check);
  list_end(check);
  list_prev(check);
  list_next(check);
  list_iterator_valid(check);
  list_push(check);
  list_pushback(check);
  list_at(check);
  list_length(check);
  list_value(check);
  list_del(check);
  list_clear(check);
  fprintf(stdout, "\n");
}
